
/*
USB中断处理
*/
#include <stdint.h>

#include "tusb_option.h"
#include "common/tusb_compiler.h"
#include "device/dcd.h"
#include "device/n32g45x.h"
#include "core/core_cm4.h"

typedef  int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef  uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;

#ifndef PACKED
#define PACKED __attribute__ ((packed))
#endif

#ifndef INLINE
#define INLINE static inline
#endif

typedef struct PACKED{
    volatile u32 addr:4;
    volatile u32 sts_tx:2;
    volatile u32 dattog_tx:1;
    volatile u32 ctrs_tx:1;
    volatile u32 kind:1;
    volatile u32 type:2;
    volatile u32 setup:1;
    volatile u32 sts_rx:2;
    volatile u32 dattog_rx:1;
    volatile u32 ctrs_rx:1;
    volatile u32 reserved:16;
}USB_EP_T;

typedef struct{
    volatile u32 frset:1;    //强制USB复位
    volatile u32 pd:1;       //断电模式
    volatile u32 lp_mode:1;  //低功耗模式
    volatile u32 fsuspd:1;   //强制挂起
    volatile u32 resum:1;    //唤醒请求
    volatile u32 reserved:3;
    volatile u32 esofm:1;    //期望的帧起始中断使能
    volatile u32 sofm:1;     //帧起始中断使能
    volatile u32 rstm:1;     //复位中断使能
    volatile u32 suspdm:1;   //挂起中断使能
    volatile u32 wkupm:1;    //唤醒中断使能
    volatile u32 errorm:1;   //错误中断使能
    volatile u32 pmaom:1;    //数据包缓冲器溢出中断使能
    volatile u32 ctrsm:1;    //正确传输中断使能
    volatile u32 res2:16;
}USB_CTRL_T;

typedef struct PACKED{
    volatile u32 id:4;
    volatile u32 dir:1;
    volatile u32 res:3;
    volatile u32 esof:1;
    volatile u32 sof:1;
    volatile u32 rst:1;
    volatile u32 suspd:1;
    volatile u32 wkup:1;
    volatile u32 error:1;
    volatile u32 pmao:1;
    volatile u32 ctrs:1;
    volatile u32 res2:16;
}USB_STS_T;

typedef struct PACKED{
    volatile u32 fnum:11;
    volatile u32 lstsof:2;
    volatile u32 lock:1;
    volatile u32 rxdm_sts:1;
    volatile u32 rxdp_sts:1;
    volatile u32 res:16;
}USB_FN_T;

typedef struct PACKED{
    volatile u32 addr:7;
    volatile u32 efuc:1;
    volatile u32 res:24;
}USB_ADDR_T;

typedef struct PACKED{
    volatile u32 res:3;
    volatile u32 buftab:13;
    volatile u32 res2:16;
}USB_BUFTAB_T;

typedef struct PACKED{
    u16 res:1;
    u16 tx_addr:15;
    u16 reserve1:16;
    u16 tx_cnt:10;
    u16 res2:6;
    u16 reserve2:16;
    u16 res3:1;
    u16 rx_addr:15;
    u16 reserve3:16;
    u16 rx_cnt:10;
    u16 num_blk:5;
    u16 blsize:1;
    u16 reserve4:16;
}USB_DESC_T;
#define USB_DESC_GET_TXADDR(addr)           (*((volatile u16*)(addr)))
#define USB_DESC_SET_TXADDR(addr,tx_addr)   *((volatile u16*)(addr)) = ((tx_addr)&0x7ff)
#define USB_DESC_GET_TXLEN(addr)            (*((volatile u16*)(addr)+2)&0x3ff)
#define USB_DESC_SET_TXLEN(addr,tx_len)     *((volatile u16*)(addr)+2) = ((tx_len) & 0x3ff)
#define USB_DESC_GET_RXADDR(addr)           (*((volatile u16*)(addr)+4))
#define USB_DESC_SET_RXADDR(addr,rx_addr)   *((volatile u16*)(addr)+4) = ((rx_addr)&0x7ff)
#define USB_DESC_GET_RXLEN(addr)            (*((volatile u16*)(addr)+6)&0x3ff)
#define USB_DESC_SET_RX_RECVLEN(addr,value) *((volatile u16*)(addr)+6) = value

typedef struct{
    union{
        volatile USB_EP_T ep[8];
        volatile uint32_t ep_value[8];
    };
    u32  res[8];        //跳过32字节
    union{
        USB_CTRL_T ctrl;
        volatile u32 ctrl_value;
    };
    union{
        volatile USB_STS_T  sts;
        volatile u32        sts_value;
    };
    volatile USB_FN_T   fn;
    union{
        volatile USB_ADDR_T  addr;
        volatile u32         addr_value;
    };
    volatile USB_BUFTAB_T buftab;
}USB_type_t;

#undef USB
#define USB ((USB_type_t *)0x40005C00)
#define USB_BUF (0x40006000)

////////////////////////////////////////////////////
//
////////////////////////////////////////////////////
//第一数据
#define MAX_EP_COUNT 8u         /*最大8个端点数*/
static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[6];
static uint8_t* ept_recv_buf[MAX_EP_COUNT];
static uint16_t ept_recv_len[MAX_EP_COUNT];
static uint16_t ept_recv_off[MAX_EP_COUNT];

uint8_t* ept_send_buf[MAX_EP_COUNT];
uint16_t ept_send_len[MAX_EP_COUNT];
uint16_t ept_send_off[MAX_EP_COUNT];

static uint16_t ept_buf_addr[MAX_EP_COUNT][2];
uint16_t ept_max_packet_size[MAX_EP_COUNT][2];
static uint8_t setup_buffer[12];

static const tusb_desc_endpoint_t ep0OUT_desc =
{
  .bLength          = sizeof(tusb_desc_endpoint_t),
  .bDescriptorType  = TUSB_DESC_ENDPOINT,

  .bEndpointAddress = 0x00,
  .bmAttributes     = { .xfer = TUSB_XFER_CONTROL },
  .wMaxPacketSize   = CFG_TUD_ENDPOINT0_SIZE,
  .bInterval        = 0
};

static const tusb_desc_endpoint_t ep0IN_desc =
{
  .bLength          = sizeof(tusb_desc_endpoint_t),
  .bDescriptorType  = TUSB_DESC_ENDPOINT,

  .bEndpointAddress = 0x80,
  .bmAttributes     = { .xfer = TUSB_XFER_CONTROL },
  .wMaxPacketSize   = CFG_TUD_ENDPOINT0_SIZE,
  .bInterval        = 0
};
//////////////////////////////////////////////////////////////////
//USB 缓存处理

typedef struct{
	uint32_t tx_addr;
	uint32_t tx_len;	// [9:0],其他保留
	uint32_t rx_addr;
	uint32_t rx_len; 	//
}USB_buftbl;

#define USB_BUF_SIZE 	(512)
#define USB_BUFTBL_END 	(0x8 * sizeof(USB_buftbl) / 2)

uint8_t	alloc_bit[USB_BUF_SIZE/8];
TU_ATTR_ALWAYS_INLINE static inline void USB_BUF_freeAll(){
	memset(alloc_bit,0,sizeof(alloc_bit));
	memset(ept_buf_addr,0,sizeof(ept_buf_addr));
	memset(ept_max_packet_size,0,sizeof(ept_max_packet_size));

	memset(ept_recv_buf,0,sizeof(ept_recv_buf));
	memset(ept_recv_len,0,sizeof(ept_recv_len));
	memset(ept_recv_off,0,sizeof(ept_recv_off));

	memset(ept_send_buf,0,sizeof(ept_send_buf));
	memset(ept_send_len,0,sizeof(ept_send_len));
	memset(ept_send_off,0,sizeof(ept_send_off));
}

typedef int (*USB_BUF_find_alloc_fn)(int null_offset);


TU_ATTR_ALWAYS_INLINE static inline uint16_t USB_BUF_alloc(int epnum,int packet_size){
	uint32_t addr = USB_BUFTBL_END;			//跳过描述表
	packet_size = (packet_size+1) & 0xfffe;
	TU_ASSERT(packet_size>=4);			//

	//包的字节对齐
		 if(packet_size<8 ) 	packet_size = 8;
	else if(packet_size<16) 	packet_size = 16;
	else if(packet_size<32) 	packet_size = 32;
	else if(packet_size<64) 	packet_size = 64;

	if(
		packet_size==8||packet_size==16||packet_size==32||packet_size==64
	){
		int 		offset = 0 + addr;
		uint8_t		*bit = alloc_bit;
		while((offset + packet_size)<=USB_BUF_SIZE){				/*缓存大小为512个字节*/
			 uint8_t 		*bit8 =  ( uint8_t*)bit;
			uint16_t 		*bit16 = (uint16_t*)bit;
			uint32_t 		*bit32 = (uint32_t*)bit;
			uint64_t 		*bit64 = (uint64_t*)bit;

			if((packet_size== 8)&&( *bit8==0)){  *bit8=-1; return offset; }
			if((packet_size==16)&&(*bit16==0)){ *bit16=-1; return offset; }
			if((packet_size==32)&&(*bit32==0)){ *bit32=-1; return offset; }
			if((packet_size==64)&&(*bit64==0)){ *bit64=-1; return offset; }

			offset += packet_size;
			bit += packet_size/8;
		}
	}

	TU_ASSERT(0);		//应该处理一些微小的块,8或者16,32,64

	return 0;

	//return addr + epnum * 64*2 /2;						//
}

////////////////////////////////////////////////////
#define USB_EPT_BIT_MASK ( \
      0x80  /*ctrs_tx*/ \
    | 0x8000 /*ctrs_rx*/ \
    | 0x800 /*setup*/ \
    | 0xF   /*addr*/ \
    | 0x100 /*kind*/ \
    | 0x600 /*type*/ )
enum{
    usb_disable = 0x0,
    usb_stall = 0x1,
    usb_nak = 0x2,
    usb_valid = 0x3,

    usb_type_bulk = 0,
    usb_type_control = 1,
    usb_type_iso = 2,
    usb_type_interrupt = 3,
    usb_type_sizeof = sizeof(USB_type_t),
    usb_desc_sizeof = sizeof(USB_DESC_T),
};

static void usb_write_packet(u8*dat,uint16_t offset_addr,uint16_t nbytes){
    //以4对齐访问USB缓存
    //  但USB内部只能处理16位
    volatile u16* usb_buf = (volatile u16*)(offset_addr * 2 + USB_BUF);
    int _nbytes = (nbytes+1)>>1;
    int i;
    u16 *send_dat = (u16*)dat;
    for(i=0;i<_nbytes;i++){
        *usb_buf = *send_dat;
        usb_buf++;
        usb_buf++;
        send_dat++;
    }
}

static void usb_read_packet(u8*dat,uint16_t offset_addr,uint16_t nbytes){
    volatile u16* usb_buf = (volatile u16*)(offset_addr * 2 + USB_BUF);
    u16 *recv_dat = (u16*)dat;
    int _nbytes = (nbytes+1)>>1;
    int i;
    for(i=0;i<_nbytes;i++){
        *recv_dat = *usb_buf;
        usb_buf++;
        usb_buf++;
        recv_dat++;
    }
}

static USB_DESC_T * usb_get_desc(int ept_num){
    //int offset = (USB->buftab.buftab + ept_num * 8) * 2;
    USB_DESC_T *desc = (USB_DESC_T *)(USB_BUF);
    return desc + ept_num;
}

static void usb_set_txlen(uint8_t ept_num,int nbytes){
    //usb_get_desc(ept_num)->tx_cnt = nbytes;
    USB_DESC_SET_TXLEN(usb_get_desc(ept_num),nbytes);
}

static void usb_set_txaddr(uint8_t ept_num,uint16_t addr){
    //usb_get_desc(ept_num)->tx_addr = addr;
    USB_DESC_SET_TXADDR(usb_get_desc(ept_num),addr);
}

static void usb_set_rxaddr(uint8_t ept_num,uint16_t addr){
    //usb_get_desc(ept_num)->rx_addr = addr;
    USB_DESC_SET_RXADDR(usb_get_desc(ept_num),addr);
}

static void usb_clr_txdts(uint8_t ept_num){
    USB_EP_T ep = USB->ep[ept_num];
    if(ep.dattog_tx){
        USB->ep_value[ept_num] =
        (USB->ep_value[ept_num] & USB_EPT_BIT_MASK)
        | (1<<6) /*dattog_tx*/
        | (1<<15) /*ctrs_rx*/
        | (1<<7) /*ctrs_tx*/;
    }
}

static void usb_clr_rxdts(uint8_t ept_num){
    USB_EP_T ep = USB->ep[ept_num];
    if(ep.dattog_rx){
        USB->ep_value[ept_num] =
        (USB->ep_value[ept_num] & USB_EPT_BIT_MASK)
        | (1<<14) /*dattog_rx*/
        | (1<<15) /*ctrs_rx*/
        | (1<<7) /*ctrs_tx*/;
    }
}


static void usb_set_rxlen(uint8_t ept_num,int nbytes){
    USB_DESC_T *desc = usb_get_desc(ept_num);
    u16 recv_len = 0;
    int num_blk = 0;
    if(nbytes>62){
        recv_len |= (1<<15);
        num_blk = nbytes>>5;
        if(nbytes&0x1f){
        }
        else{
            num_blk -= 1;
        }
    }
    else{
        if(nbytes&1){
            num_blk = nbytes>>1;
        }
        else{
            num_blk = (nbytes>>1) + 1;
        }
    }
    //num_blk <<= 10;
    recv_len |= (num_blk & 0x1f)<<10;
    USB_DESC_SET_RX_RECVLEN(desc,recv_len);
}

static void usb_set_txsts(uint8_t ept_num,int sts){
    uint32_t ep_sts = USB->ep_value[ept_num];
    ep_sts &=
      0x30 /*sts_tx*/
      | USB_EPT_BIT_MASK;

    if(sts & 0x1){
        ep_sts ^= 0x1<<4;
    }
    if(sts & 0x2){
        ep_sts ^= 0x2<<4;
    }
    USB->ep_value[ept_num] = ep_sts
    | 0x8000 /*ctrs_rx*/
    | 0x80   /*ctrs_tx*/
    ;
}

static void usb_set_rxsts(uint8_t ept_num,int sts){
    register uint16_t ep_sts = USB->ep_value[ept_num];
    ep_sts &=
      0x3000 /*sts_tx*/
      |USB_EPT_BIT_MASK;

#if 1
    if(sts & 0x1){
        ep_sts ^= 0x1<<12;
    }
    if(sts & 0x2){
        ep_sts ^= 0x2<<12;
    }
#else
    if(sts & 0x1){
        ep_sts |= 0x1<<12;
    }
    if(sts & 0x2){
        ep_sts |= 0x2<<22;
    }
#endif
    USB->ep_value[ept_num] = ep_sts
    | 0x8000 /*ctrs_rx*/
    | 0x80   /*ctrs_tx*/
    ;
}

static void usb_clr_ctrs_rx(uint8_t ept_num){
    USB->ep_value[ept_num] &= (0x7fff&USB_EPT_BIT_MASK);
}

static void usb_clr_ctrs_tx(uint8_t ept_num){
    USB->ep_value[ept_num] &= (0xff7f&USB_EPT_BIT_MASK);
}
//以上为一些硬件操作
////////////////////////////////////////////////////////////////////////

/*扩展处理写*/

static void dcd_transmit_packet(int ept_num){
	uint16_t buf_addr = ept_buf_addr[ept_num][TUSB_DIR_IN];
	uint8_t* buf = ept_send_buf[ept_num];
	uint16_t len = ept_send_len[ept_num];
	uint16_t off = ept_send_off[ept_num];
	uint16_t packet_size = ept_max_packet_size[ept_num][TUSB_DIR_IN];
	int remaining = len - off;
	if(remaining>packet_size)
		remaining = packet_size;
    if(remaining<0)
        remaining = 0;
	usb_write_packet(buf + off,buf_addr,remaining);

	ept_send_off[ept_num] += remaining;		//指向下一个数据

	usb_set_txlen(ept_num,remaining);

	//处理发送
	usb_set_txsts(ept_num, usb_valid);
}

INLINE void usb_rx_handler(USB_STS_T sts){
    int ept_num = sts.id;
    USB_EP_T ept = USB->ep[ept_num];
    uint8_t ept_addr = ept.addr;
    if(!ept.ctrs_rx){
        return;
    }

    if(ept.setup){
        //setupPC事件
        int recv_len = USB_DESC_GET_RXLEN(usb_get_desc(ept_num));
        int recv_addr =USB_DESC_GET_RXADDR(usb_get_desc(ept_num));
        if(recv_len==8){
            int rx_addr = ept_buf_addr[ept_num][TUSB_DIR_OUT];

            usb_set_rxsts(0,usb_nak);
            usb_set_txsts(0,usb_nak);

            usb_read_packet(setup_buffer,rx_addr,recv_len);

            dcd_event_setup_received(0,setup_buffer,1);
        }
    }
    else if(ept.ctrs_rx){
        int len = USB_DESC_GET_RXLEN(usb_get_desc(ept_num));
        int rx_addr = ept_buf_addr[ept_num][TUSB_DIR_OUT];
        int max_packet = ept_max_packet_size[ept_num][TUSB_DIR_OUT];
        TU_ASSERT(len<max_packet);
        uint8_t *buf = ept_recv_buf[ept_num];

        usb_read_packet(buf + ept_recv_off[ept_num],rx_addr,len);
        ept_recv_off[ept_num] += len;
        int total_len = ept_recv_len[ept_num];
        int cur_len = ept_recv_off[ept_num];

        usb_clr_ctrs_rx(ept_num);
        if(len<max_packet || ept_num== 0 || cur_len==total_len){
            dcd_event_xfer_complete(0,ept_addr,len,XFER_RESULT_SUCCESS,true);
        }
        else{
            //处理剩余接收数据
            int remaining = ept_recv_len[ept_num] - ept_recv_off[ept_num];		//剩余数据
			if(remaining>ept_max_packet_size[ept_num][TUSB_DIR_OUT])
				remaining = ept_max_packet_size[ept_num][TUSB_DIR_OUT];

			//当完成后触发
            usb_set_rxlen(ept_num,remaining);
            usb_set_rxsts(ept_addr&0x7f,usb_valid);
        }
    }

    if(ept_num==0){
    //端口0
        usb_set_rxlen(ept_num,CFG_TUD_ENDPOINT0_SIZE);
        usb_clr_ctrs_rx(ept_num);
    }
}

INLINE void usb_tx_handler(USB_STS_T sts){
    int ept_num = sts.id;
    //快速访问
    USB_EP_T ept = USB->ep[ept_num];
    uint8_t ept_addr = ept.addr;
    if(!ept.ctrs_tx){
        return;
    }
    //USB->ep[ept_num].ctrs_tx = 0;   //清楚标志
    usb_clr_ctrs_tx(ept_num);

    int total_len = ept_send_len[ept_num];
    int offset = ept_send_off[ept_num];
    if(offset==total_len){
        //发送完成
        dcd_event_xfer_complete(0,ept_num|TUSB_DIR_IN_MASK,total_len,XFER_RESULT_SUCCESS,true);
    }
    else{
        //继续发送
        dcd_transmit_packet(ept_num);
    }
}

static void dcd_handle_bus_reset(void);
void dcd_int_handler(uint8_t rhport) {
    USB_STS_T sts = USB->sts;
    USB_CTRL_T ctrl = USB->ctrl;
    if(sts.sof&&ctrl.sofm){
        USB->sts.sof = 0;
        dcd_event_sof(0,USB->fn.fnum,1);
    }

    if(sts.rst){
        //重置
        USB->sts.rst = 0;
        dcd_handle_bus_reset();
        dcd_event_bus_reset(0,TUSB_SPEED_FULL,1);
        return;
    }

    while((sts=USB->sts).ctrs){
        //正确传输中断
        if(sts.dir){
            usb_rx_handler(sts);
        }
        else{
            usb_tx_handler(sts);
        }

        //dcd_int_handler(0);
    }

    if(USB->sts.wkup&&ctrl.wkupm){
        //唤醒中断
        USB->ctrl.fsuspd = 0;       //关闭强制挂起
        USB->ctrl.lp_mode = 0;      //关闭低功耗
        USB->sts.wkup = 0;
        dcd_event_bus_signal(0,DCD_EVENT_RESUME,1);
    }
    if(USB->sts.suspd){
        //挂起中断
        USB->ctrl.fsuspd = 1;
        USB->ctrl.lp_mode = 1;
        USB->sts.suspd = 0;
        dcd_event_bus_signal(0,DCD_EVENT_SUSPEND,1);
    }

    if(sts.esof&& ctrl.esofm){
        USB->sts.sof = 0;
    }

    if(USB->sts.error){
        //错误中断
        USB->sts.error =0;
    }
    if(USB->sts.pmao){
        //溢出中断
        USB->sts.pmao = 0;
    }
}

/*主中断处理*/
void USB_LP_CAN1_RX0_IRQHandler(){
    dcd_int_handler(0);
}

//////////////////////////////////////////////////
//tud操作
int usb_reset = 0;
static void dcd_handle_bus_reset(void){
	//重置中断,需要打开断点0与1
	//初始化一些东西
	USB->addr_value = 0x00;

	USB_BUF_freeAll();

	dcd_edpt_open(0,&ep0OUT_desc);

	dcd_edpt_open(0,&ep0IN_desc);

	usb_reset++;

	USB->addr_value = 0x80;		//设置设备的地址为0
}

void dcd_init (uint8_t rhport)
{
    (void) rhport;

    //需要设置一些USB外设参数
    USB->ctrl.frset = 0;
    USB->sts_value = 0;           //关闭所有状态
    USB->buftab.buftab = 0;       //默认USB表在缓存区位置
    USB->addr_value = 0x80;		//地址为0,USB core开始工作

        //设置中断
    //USB->ctrl |= (USB_SOF_INT | USB_RST_INT | USB_SP_INT | USB_WK_INT | USB_TC_INT);
    USB->ctrl_value |=
        0x200       /*sof*/
        |(1<<10)   /* rst */
        |(1<<11)   /* sp */
        |(1<<12)   /* wk */
        |(1<<15)   /* ctrs_tx */;


    dcd_handle_bus_reset();
    //最后开启连接
    dcd_connect(0);
}

void dcd_connect(uint8_t rhport)
{
	USB->ctrl.pd = 0;                       //退出断电模式
    *(volatile u32*)(0x40001820) |= 1<<28;
}

void dcd_disconnect(uint8_t rhport)
{
	USB->ctrl.pd = 1;                       //进入断电模式
    *(volatile u32*)(0x40001820) &= ~(1<<28);
}

void dcd_sof_enable(uint8_t rhport, bool en)
{
	//可以实现.更多不实现
  (void) rhport;
  (void) en;
  // TODO implement later
}

void dcd_edpt_close_all (uint8_t rhport)
{
	//不实现
  (void) rhport;
}

bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes)
{
	//需要实现
  (void) rhport;
  (void) ep_addr;
  (void) buffer;
  (void) total_bytes;
  uint8_t epnum = tu_edpt_number(ep_addr);
  u8 dir = tu_edpt_dir(ep_addr);

  if(dir==TUSB_DIR_OUT){
	  //主机输出.设备输入
	  u8 *buf = buffer;
	  if(ep_addr==0 && buffer==NULL){
		  //控制端
		  buf = (uint8_t*)_setup_packet;
	  }

		//设置接收缓存
		ept_recv_buf[epnum] = buf;
		ept_recv_len[epnum] = total_bytes;
		ept_recv_off[epnum] = 0;

		if(total_bytes>ept_max_packet_size[epnum][TUSB_DIR_OUT])
			total_bytes = ept_max_packet_size[epnum][TUSB_DIR_OUT];

		//设置接收数量
		//USB_SET_RXLEN(epnum,total_bytes);
        usb_set_rxlen(epnum,total_bytes);

	  	//设置可以接收缓存状态
	  	//USB_SET_RXSTS(epnum,USB_RX_VALID);
        usb_set_rxsts(epnum,usb_valid);
  }
  else{
	  //IN
	  //主机输入,设备输出

		ept_send_buf[epnum] = buffer;
		ept_send_len[epnum] = total_bytes;
		ept_send_off[epnum] = 0;
		dcd_transmit_packet(epnum);
  }
  return 1;
}

void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
{
	//需要实现
	u8 epnum = tu_edpt_number(ep_addr);
	u8 dir = tu_edpt_dir(ep_addr);
	if(dir==TUSB_DIR_IN)
		//{USB_SET_TXSTS(epnum,USB_TX_STALL);}
        usb_set_txsts(epnum,usb_stall);
	else
		//{USB_SET_RXSTS(epnum,USB_RX_STALL);}
        usb_set_rxsts(epnum,usb_stall);
}

void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr)
{
	//需要实现
	u8 epnum = tu_edpt_number(ep_addr);
	u8 dir = tu_edpt_dir(ep_addr);
	USB_EP_T ep = USB->ep[epnum];
	if(dir==TUSB_DIR_IN){
		// if((epnum_reg&USB_TRANS_TYPE)!=USB_EPT_ISO){
		// 	USB_SET_TXSTS(epnum,USB_TX_NAK);	//如果不是ISO,则需要清除
		// }

        if(ep.type!=0b10){
            /*!= ISO*/
            usb_set_txsts(epnum,usb_nak);
        }
		//USB_CLEAR_TXDTS(epnum);
        usb_clr_txdts(epnum);
	}
	else{
		// if((epnum_reg&USB_TRANS_TYPE)!=USB_EPT_ISO){
		// 	USB_SET_RXSTS(epnum,USB_TX_NAK);	//如果不是ISO,则需要清除
		// }
        if(ep.type!=0b10){
            /*!=ISO*/
            usb_set_rxsts(epnum,usb_nak);
        }

		//USB_CLEAR_RXDTS(epnum);
        usb_clr_rxdts(epnum);
	}
}

// Enable device interrupt
void dcd_int_enable (uint8_t rhport)
{
    u32 prio = NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0,0);
    NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn,prio);
    NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
}

// Disable device interrupt
void dcd_int_disable (uint8_t rhport)
{
    NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn);
}

void dcd_set_address (uint8_t rhport, uint8_t dev_addr)
{
	//响应 NAK
	dcd_edpt_xfer(0,TUSB_DIR_IN_MASK | 0x00,NULL,0);
}

void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request)
{
  (void) rhport;

    if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE &&
        request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD &&
        request->bRequest == TUSB_REQ_SET_ADDRESS )
    {
        uint8_t const dev_addr = (uint8_t) request->wValue;

        // Setting new address after the whole request is complete
        USB->addr.addr = dev_addr;
        USB->addr.efuc = 1;
    }
}

void dcd_remote_wakeup (uint8_t rhport)
{
	USB->ctrl.resum = 1;        //唤醒
}

bool dcd_edpt_open            (uint8_t rhport, tusb_desc_endpoint_t const * desc_ep){
	//需要实现
  (void) rhport;
  u32 wType;
  switch (desc_ep->bmAttributes.xfer)
  {
  case TUSB_XFER_CONTROL	: wType = usb_type_control;	break;	//控制端口
  case TUSB_XFER_BULK		: wType = usb_type_bulk;	break;		//批量传输
  case TUSB_XFER_INTERRUPT	: wType = usb_type_interrupt;	break;		//中断传输
  case TUSB_XFER_ISOCHRONOUS: wType = usb_type_iso;	break;		//同步传输
  default:
  //错误
		TU_ASSERT(0);
	  	break;
  }
  int dir = tu_edpt_dir(desc_ep->bEndpointAddress);					//方向
  int packet_sz = tu_edpt_packet_size(desc_ep);  	//包大小
  uint8_t epnum = tu_edpt_number(desc_ep->bEndpointAddress);

  //设置EP类型,与地址. 使用默认地址
  USB_EP_T ep = {0};
  int addr =  tu_edpt_number(desc_ep->bEndpointAddress);
  ep.type = wType;
  ep.ctrs_rx = 1;
  ep.ctrs_tx = 1;
  ep.addr = addr;
  if(epnum>=8) TU_ASSERT(0);

  USB->ep[epnum] = ep;	//设置16位EP属性

  //申请缓存
  uint8_t ep_addr = USB->ep[epnum].addr;
  int ep_buf = USB_BUF_alloc(ep_addr,packet_sz);
  ept_buf_addr[epnum][dir] = ep_buf;				//设置接收或者发送地址
  ept_max_packet_size[epnum][dir] = packet_sz;

  if(dir==TUSB_DIR_IN){
        //设置传送地址
        //现在不使用双倍缓存
        //   USB_SET_TX_ADDRESS(epnum,ep_buf);
        //   USB_CLEAR_TXDTS(epnum);
        //   USB_SET_TXSTS(epnum,USB_TX_NAK);
        usb_set_txaddr(epnum,ep_buf);
        usb_clr_txdts(epnum);
        usb_set_txsts(epnum,usb_nak);
  }
  else{
        //设置接收地址
        //现在不使用双倍缓存
        //   USB_SET_RX_ADDRESS(epnum,ep_buf);
        //   USB_CLEAR_RXDTS(epnum);
        //   USB_SET_RXLEN(epnum, packet_sz);
        //   USB_SET_RXSTS(epnum, USB_RX_VALID);
        usb_set_rxaddr(epnum,ep_buf);
        usb_clr_rxdts(epnum);
        usb_set_rxsts(epnum,usb_nak);
  }

  return 1;
}

